/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.database.metamodel;

import com.jb.framework.DataSourceManager;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.List;


public class Schema extends BaseDatabaseEntity {
    String catalogName;
    String schemaName;
    Table table;

    public Schema(String pSchemaName, String pCatalogName) {
        schemaName = pSchemaName;
        catalogName = pCatalogName;
        setName(pSchemaName);
    }

    public Schema(String pSchemaName) {
        schemaName = pSchemaName;
        setName(pSchemaName);
    }

    public Table getTable() {
        return table;
    }

    public Table getTable(String name) throws SQLException {
        Table table = (Table) getChildByTypeAndName(Table.class, name);

        if (table == null) {
            List list = getTables(name);

            if (list.size() == 1) {
                return (Table) list.get(0);
            } else {
                return null; //no found
            }
        }

        return table;
    }

    public void setTableName(String tableName) {
        table = (Table) getChildByTypeAndName(Table.class, tableName);
    }

    public List getTables() throws SQLException {
        return getTables("%");
    }

    public List getTables(String filter) throws SQLException {
        this.removeChildren();
        populate("TABLE", filter);
        return getChildrenByType(Table.class);
    }

    public View getView(String name) throws SQLException {
        View view = (View) this.getChildByTypeAndName(View.class, name);

        if (view == null) {
            List list = getViews(name);

            if (list.size() == 1) {
                return (View) list.get(0);
            } else {
                return null; //no found
            }
        }
        return view;
    }

    public List getViews(String filter) throws SQLException {
        this.removeChildren();
        populate("VIEW", filter);

        return this.getChildrenByType(View.class);
    }

    public void assign(ResultSet crs) throws SQLException {
    }

    public void deleteTable(String tableName) {
        Table table = (Table) getChildByTypeAndName(Table.class, tableName);

        if (table != null) {
            executeSQL("drop table " + tableName);
            this.getChildren().remove(table);

            try {
                getTables();
            } catch (SQLException e) {
                e.printStackTrace();
                //
            }
        }
    }
    public void populate(Connection conn, String tableType, String filter)
        throws SQLException {
        ResultSet trs = null;

        try {
            String[] types = { tableType };
            //this is mysql specific
         //   conn.createStatement().execute("use " + schemaName + ";");

            if (catalogName == null) {
                catalogName = schemaName;
            }

            trs = conn.getMetaData().getTables(catalogName, schemaName, (filter == null) ? "%" : filter, types);

            while (trs.next()) {
                String type = trs.getString(4);
                Table table;

                if ("TABLE".equals(type)) {
                    table = new Table();
                } else if ("VIEW".equals(type)) {
                    table = new View();
                } else {
                    continue;
                }

                table.assign(trs);
                addChild(table);
            }

            trs.close();
            trs = null;
        } finally {
            if (trs != null) {
                try {
                    trs.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void populate(String tableType, String filter)
        throws SQLException {
        Connection conn = null;

        try {
            conn = DataSourceManager.getConnection(this);
            this.populate(conn, tableType, filter);
            conn.commit();
        } finally {
            if (conn != null) {
                DataSourceManager.releaseConnection(this, conn);
            }
        }
    }
}
